# main.py

from data_preparation import load_and_preprocess_data
from train_dqn import train_dqn_agent
from manual_tuning import manual_hyperparameter_tuning
from evaluation_and_visualization import (
    evaluate_best_params,
    evaluate_manual_params,
    plot_accuracies,
    plot_rl_rewards,
    plot_manual_accuracies
)


def run_experiment():
    # 加载和预处理数据
    X_train, X_val, X_test, y_train, y_val, y_test = load_and_preprocess_data()

    # 训练DQN代理
    print("Training DQN Agent...")
    trained_agent, rl_episode_rewards, rl_best_acc = train_dqn_agent(
        X_train, y_train, X_val, y_val, episodes=500,
        log_file='episode_hyperparams.csv',
        checkpoint_path='dqn_checkpoint.pth',
        cache_file='evaluation_cache.json',
        path_file='agent_paths.json',
        early_stop_patience=500  # 根据需要调整
    )

    # 手动调节超参数
    print("\nStarting Manual Hyperparameter Tuning...")
    manual_accuracies, manual_params = manual_hyperparameter_tuning(
        X_train, y_train, X_val, y_val
    )

    # 可视化RL调节过程中的奖励变化
    print("\nPlotting RL Agent Training Progress...")
    plot_rl_rewards(rl_episode_rewards)

    # 可视化手动调节的准确率分布
    print("\nPlotting Manual Tuning Results...")
    plot_manual_accuracies(manual_accuracies, manual_params)

    # 绘制RL调节与手动调节的对比
    print("\nPlotting RL Tuned vs Manual Tuned Accuracies...")
    plot_accuracies(rl_best_acc, manual_accuracies)

    # 使用RL代理选择的最佳超参数训练最终模型并评估
    print("\nEvaluating Best Hyperparameters from RL Agent...")
    best_params_rl, test_accuracy_rl = evaluate_best_params(
        trained_agent, X_train, y_train, X_val, y_val, X_test, y_test
    )

    # 使用手动调节中表现最好的超参数训练最终模型并评估
    print("\nEvaluating Best Hyperparameters from Manual Tuning...")
    best_params_manual, test_accuracy_manual = evaluate_manual_params(
        manual_params, X_train, y_train, X_val, y_val, X_test, y_test
    )

    # 最终对比
    print("\nFinal Comparison:")
    print(f"RL Tuned Accuracy: {test_accuracy_rl * 100:.2f}%")
    print(f"Manual Tuned Accuracy: {test_accuracy_manual * 100:.2f}%")

if __name__ == "__main__":
    run_experiment()
